package com.jiangjiang.eshop.order.service.impl;

import com.jiangjiang.eshop.inventory.service.InventoryService;
import com.jiangjiang.eshop.membership.service.MembershipService;
import com.jiangjiang.eshop.order.constant.PublishedComment;
import com.jiangjiang.eshop.order.constant.ReturnGoodsApplyStatus;
import com.jiangjiang.eshop.order.domain.OrderInfoEntity;
import com.jiangjiang.eshop.order.dto.OrderInfoDTO;
import com.jiangjiang.eshop.order.dto.ReturnGoodsApplyDTO;
import com.jiangjiang.eshop.order.price.v1.factory.DefaultOrderPriceCalculatorFactory;
import com.jiangjiang.eshop.order.price.v1.factory.DiscountOrderPriceCalculatorFactory;
import com.jiangjiang.eshop.order.price.v1.factory.GiftOrderPriceCalculatorFactory;
import com.jiangjiang.eshop.order.service.OrderInfoService;
import com.jiangjiang.eshop.order.service.OrderService;
import com.jiangjiang.eshop.order.service.ReturnGoodsApplyService;
import com.jiangjiang.eshop.order.status.LoggedOrderStateManager;
import com.jiangjiang.eshop.promotion.service.PromotionFacadeService;
import com.jiangjiang.eshop.schedule.service.ScheduleService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 * @ClassName OrderFacadeServiceImpl
 * @Description TODO
 * @Author jhw
 * @Date 2021/6/3 21:53
 * @Version 1.0
 **/
@Slf4j
@Service
public class OrderServiceImpl implements OrderService {

    @Autowired
    private OrderInfoService orderInfoService;
    @Autowired
    private LoggedOrderStateManager orderStateManager;
    @Autowired
    private InventoryService inventoryService;
    @Autowired
    private ScheduleService scheduleService;
    @Autowired
    private MembershipService membershipService;
    @Autowired
    private ReturnGoodsApplyService returnGoodsApplyService;

    @Override
    public Boolean informPublishCommentEvent(Long orderId) {
       try {
           OrderInfoEntity order = orderInfoService.getById(orderId);
           order.setPublishedComment(PublishedComment.YES);
           orderInfoService.updateById(order);
       }catch (Exception e){
           log.warn("OrderServiceImpl informPublishCommentEvent error",e);
       }
        return false;
    }

    @Override
    public List<OrderInfoDTO> listNotPublishedCommentOrders() {
      try {
          return orderInfoService.listNotPublishedCommentOrders();
      }catch (Exception e){
          log.warn("OrderServiceImpl listNotPublishedCommentOrders error",e);
      }
        return new ArrayList<>();
    }

    @Override
    public Boolean informBatchPublishCommentEvent(List<Long> orderIds) {
        try {
            for(Long orderId : orderIds) {
                informPublishCommentEvent(orderId);
            }
            return true;
        } catch (Exception e) {
            log.error("error", e);
            return false;
        }
    }

    @Override
    public Boolean informGoodsDeliveryFinishedEvent(Long orderId) {
        try {
            OrderInfoDTO order = orderInfoService.queryById(orderId);
            orderStateManager.finishDelivery(order);
        } catch (Exception e) {
            log.warn("OrderServiceImpl informGoodsDeliveryFinishEvent error", e);
        }
        return false;
    }

    @Override
    public Boolean informReturnGoodsWorksheetRejectedEvent(Long orderId) {
       try {
           OrderInfoDTO order = orderInfoService.queryById(orderId);
           orderStateManager.rejectReturnGoodsApply(order);
           returnGoodsApplyService.updateStatus(orderId, ReturnGoodsApplyStatus.REJECTED);
       }catch (Exception e){
           log.warn("OrderServiceImpl informReturnGoodsWorksheetRejectedEvent error",e);
       }
        return false;
    }

    @Override
    public Boolean informReturnGoodsWorksheetApprovedEvent(Long orderId) {
        try {
            OrderInfoDTO order = orderInfoService.queryById(orderId);
            orderStateManager.passedReturnGoodsApply(order);
            returnGoodsApplyService.updateStatus(orderId, ReturnGoodsApplyStatus.PASSED);
        }catch (Exception e){
            log.warn("OrderServiceImpl informReturnGoodsWorksheetRejectedEvent error",e);
        }
        return false;
    }

    @Override
    public Boolean informReturnGoodsReceivedEvent(Long orderId) {
        try {
            OrderInfoDTO orderInfo = orderInfoService.queryById(orderId);
            orderStateManager.confirmReceivedReturnGoods(orderInfo);
            return true;
        }catch (Exception e){
            log.warn("OrderServiceImpl informReturnGoodsReceivedEvent error",e);
        }
        return false;
    }

    @Override
    public Boolean informReturnGoodsInputOrderApprovedEvent(Long orderId) {
       try {
           OrderInfoDTO orderInfo = orderInfoService.queryById(orderId);
           orderStateManager.finishedInputReturnGoods(orderInfo);
           return true;
       }catch (Exception e){
           log.warn("OrderServiceImpl informReturnGoodsInputOrderApprovedEvent error",e);
       }
        return false;
    }

    @Override
    public Boolean informRefundFinishedEvent(Long orderId) {
        try {
            OrderInfoDTO orderInfo = orderInfoService.queryById(orderId);
            orderStateManager.finishedRefund(orderInfo);
            return true;
        }catch (Exception e){
            log.warn("OrderServiceImpl informRefundFinishedEvent error",e);
        }
        return false;
    }

    @Override
    public OrderInfoDTO getOrderById(Long orderId) {
        try {
          return   orderInfoService.queryById(orderId);
        } catch (Exception e){
            log.warn("OrderServiceImpl getOrderById error",e);
        }
        return null;
    }

    /**
     * 执行支付成功之后的业务操作（此处是一个天然的分布式事务场景）
     *
     * @param orderInfoId 订单id
     * @return 处理结果
     */
    @Override
    public Boolean informPayOrderSucceed(Long orderInfoId) {
        try {
            OrderInfoDTO order = orderInfoService.queryById(orderInfoId);
            // 变更订单状态
            orderStateManager.pay(order);
            // 通知库存，进行库存扣减
            inventoryService.informPayOrderEvent(order);
            // 调度中心调度销售出库
            scheduleService.informPayOrderEvent(order);
            // 会员中心计算积分
            membershipService.informPayOrderEvent(order.getUserAccountId(), order.getTotalAmount());
            return true;

        } catch (Exception e) {
            log.warn("orderInfoServiceImpl informPayOrderSucceed error", e);
        }
        return false;
    }
}
